﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Simple.Common.Data;
using Simple.Entity;
using Simple.Common.Pager;
using Simple.ViewModel;
using Simple.Common.Core.Pager;
using System.Data.Entity;
using Simple.Common.Core.Log;
using Simple.Common.EasyUICommon;
using EntityFramework.Extensions;
using Simple.Entity.Models;
using Simple.Services.Events;

namespace Simple.Service
{
    public class RoleService : ApplicationService
    {
        private readonly WorkEfRepository<Sys_User> _userRepository;
        private readonly WorkEfRepository<Sys_Role> _roleRepository;
        private readonly WorkEfRepository<Sys_Menu> _menuRepository;
        private readonly WorkEfRepository<Sys_RoleForMenu> _roleForMenuRepository;
        private readonly IEventPublisher _eventPublisher;
        private const string _removeMenu = "#"; //JsTree会有一个#的根节点 需要去除

        public RoleService(WorkEfRepository<Sys_Role> roleRepository, WorkEfRepository<Sys_User> userRepository, WorkEfRepository<Sys_Menu> menuRepository, WorkEfRepository<Sys_RoleForMenu> roleForMenuRepository, IEventPublisher eventPublisher)
        {
            _userRepository = userRepository;
            _roleRepository = roleRepository;
            _menuRepository = menuRepository;
            _roleForMenuRepository = roleForMenuRepository;
            _eventPublisher = eventPublisher;
        }

        public Sys_Role FindById(long id)
        {
            return _roleRepository.Find(id);
        }

        public IPagedList<RoleListModel> GetRoles(SimpleMvcPage page, RoleQueryModel queryModel)
        {

            var query = from a in _roleRepository.TableNoTracking
                        select new RoleListModel
                        {
                            Id = a.Id,
                            CreateTime = a.CreateTime,
                            RoleName = a.RoleName
                        };
            if (queryModel != null)
            {
                if (!string.IsNullOrEmpty(queryModel.RoleName))
                {
                    query = query.Where(m => m.RoleName.Contains(queryModel.RoleName));
                }

                if (queryModel.StartTime != null)
                {
                    query = query.Where(m => DbFunctions.DiffDays(m.CreateTime, queryModel.StartTime) <= 0);
                }

                if (queryModel.EndTime != null)
                {
                    query = query.Where(m => DbFunctions.DiffDays(m.CreateTime, queryModel.EndTime) >= 0);
                }
            }

            var users = query.ToPagedList(page);
            return users;

        }

        public SimpleResult Add(Sys_Role sys_Role)
        {
            int count = _roleRepository.TableNoTracking.Count(m => m.RoleName == sys_Role.RoleName);
            if (count > 0)
            {
                return GetError("已经存在同名角色");
            }
            int ret = _roleRepository.Add(sys_Role);
            if (ret > 0)
                _eventPublisher.EntityInserted<Sys_Role>(sys_Role);
            return GetResult(ret);
        }

        public SimpleResult Update(Sys_Role sys_Role)
        {
            int ret = _roleRepository.Update(sys_Role);
            if (ret > 0)
                _eventPublisher.EntityUpdated<Sys_Role>(sys_Role);
            return GetResult(ret);
        }

        public SimpleResult Delete(long roleId)
        {
            int count = _userRepository.TableNoTracking.Count(m => m.RoleId == roleId);
            if (count > 0)
            {
                return GetError("已经存在关联角色的用户，不能删除");
            }
            var delRole = _roleRepository.Find(roleId);
            if (delRole == null)
            {
                return GetError();
            }
            int ret = _roleRepository.Delete(delRole);
            if (ret > 0)
                _eventPublisher.EntityDeleted<Sys_Role>(delRole);
            return GetResult(ret);
        }

        public List<MenuTreeListModel> GetMenuTree(long roleId)
        {
            List<string> menuIdList = _roleForMenuRepository.TableNoTracking.Where(m => m.RoleId == roleId).Select(m => m.MenuId.ToString()).ToList();
            List<MenuTreeListModel> model = _menuRepository.TableNoTracking.OrderBy(m => m.ParentId).ThenBy(m => m.Sort).Select(a => new MenuTreeListModel
            {
                id = a.Id.ToString(),
                icon = a.Icon,
                sort = a.Sort,
                text = a.MenuName,
                state = new StateClass { opened = false },
                parent=a.ParentId.ToString()
            }).ToList();
            List<MenuTreeListModel> reModel = new List<MenuTreeListModel>();
            
            foreach (var item in model)
            {
                item.children = model.Where(m => m.parent == item.id).ToList();
                if (item.parent == "0")
                {
                    item.state.opened = true;
                    reModel.Add(item);
                }
            }

            foreach (var item in model)
            {
                if (item.children == null || item.children.Count == 0)
                {
                    item.state.selected = menuIdList.Count(m => m == item.id) > 0;
                }
            }

            return reModel;
        }

        public SimpleResult DistributionAction(long roleId, string menuIdList)
        {
            var ret = _roleForMenuRepository.Table.Where(m => m.RoleId == roleId).Delete();
            if (!string.IsNullOrEmpty(menuIdList))
            {
                List<Sys_RoleForMenu> roleForMenuList = new List<Sys_RoleForMenu>();
                foreach (var menuId in menuIdList.Split(',').Distinct())
                {
                    if (menuId == _removeMenu) continue;
                    roleForMenuList.Add(new Sys_RoleForMenu()
                    {
                        RoleId = roleId,
                        MenuId = long.Parse(menuId)
                    });
                }
                ret = _roleForMenuRepository.AddRange(roleForMenuList);
            }

            return GetResult(ret);
        }



    }
}
